#include "dllmain.h"

#define SAMP_DLL "samp.dll"
bool								isBadPtr_handlerAny ( void *pointer, ULONG size, DWORD dwFlags );
bool								isBadPtr_readAny ( void *pointer, ULONG size );
bool								isBadPtr_writeAny ( void *pointer, ULONG size );
#define SAMP_CMP_03DR1  "C70424C97E9C8F442430"  
#define SAMP_CMP_03DR2  "0074201000A30B100073"  
/*#define SAMP_CMP		"6A088D4C2420518D4C24"
#define SAMP_CMP		"C70424C97E9C8F442430" 
#define SAMP_CMP        "6A088D4C2420518D4C24" 
#define SAMP_CMP        "5E2F060083C40CEB4B55"
#define SAMP_CMP        "AE6B020080BE84010000"
#define SAMP_CMP        "766A8B060FB6481451E8"*/
bool t = false;


bool isBadPtr_handlerAny ( void *pointer, ULONG size, DWORD dwFlags )
{
	DWORD						dwSize;
	MEMORY_BASIC_INFORMATION	meminfo;

	if ( NULL == pointer )
		return true;

	memset( &meminfo, 0x00, sizeof(meminfo) );
	dwSize = VirtualQuery( pointer, &meminfo, sizeof(meminfo) );

	if ( 0 == dwSize )
		return true;

	if ( MEM_COMMIT != meminfo.State )
		return true;

	if ( 0 == (meminfo.Protect & dwFlags) )
		return true;

	if ( size > meminfo.RegionSize )
		return true;

	if ( (unsigned)((char *)pointer - (char *)meminfo.BaseAddress) > (unsigned)(meminfo.RegionSize - size) )
		return true;

	return false;
}

bool isBadPtr_readAny ( void *pointer, ULONG size )
{
	return isBadPtr_handlerAny( pointer, size, PAGE_READONLY | PAGE_READWRITE | PAGE_WRITECOPY | PAGE_EXECUTE_READ |
								PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY );
}

bool isBadPtr_writeAny ( void *pointer, ULONG size )
{
	return isBadPtr_handlerAny( pointer, size,
								PAGE_READWRITE | PAGE_WRITECOPY | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY );
}

void SAMPBase::Initialize()
{

	if(!t)
	{
	multi = 1;
	//Get SAMPBaseAddress
	//Check if we run in multiplayer
	if(!multi)
		{
			//if not set dw_SAMPBaseAddress to zero			
			dw_SAMPBaseAddress = 0;
			//and continue with singleplayer stuff

		}
	uint32_t dll_adr;
	Log("get samp base address");

	void *temp = (void*)GetModuleHandle(SAMP_DLL);

	__asm mov dll_adr, eax

	dw_SAMPBaseAddress = dll_adr;

	if(dw_SAMPBaseAddress == NULL)
	{
		MessageBox(NULL,"SAMPBase::Initialize():\ndw_SAMPBaseAddress is not valid","Error",0);
		return;
	}

	Log("Set p_SAMP");
	p_SAMP = (struct stSAMP*)( UINT_PTR ) * ( uint32_t * ) ( (uint8_t *) (void *)((uint8_t *)dw_SAMPBaseAddress + SAMP_INFO_OFFSET) );
	
	Log("Check p_SAMP");
	if (isBadPtr_writeAny(p_SAMP, sizeof(stSAMP)) )
		return;

	if ( isBadPtr_writeAny(p_SAMP->pPools, sizeof(stSAMPPools)) )
		return;
	
	
	p_Players = p_SAMP->pPools->pPool_Player;
	if ( isBadPtr_writeAny(p_Players, sizeof(stPlayerPool)) )
		return;
	
	p_Vehicles = p_SAMP->pPools->pPool_Vehicle;
	if ( isBadPtr_writeAny(p_Vehicles, sizeof(stVehiclePool)) )
		return;

	p_Chat = (struct stChatInfo *)( UINT_PTR ) * ( uint32_t * ) ( (uint8_t *) (void *)((uint8_t *)dw_SAMPBaseAddress + SAMP_CHAT_INFO_OFFSET) );
	if ( isBadPtr_writeAny(p_Chat, sizeof(stChatInfo)) )
		return;

	p_Input = (struct stInputInfo *)( UINT_PTR ) * ( uint32_t * ) ( (uint8_t *) (void *)((uint8_t *)dw_SAMPBaseAddress + SAMP_CHAT_INPUT_INFO_OFFSET) );
	if ( isBadPtr_writeAny(p_Input, sizeof(stInputInfo)) )
		return;

	p_DeathList = (struct stKillInfo *)( UINT_PTR ) * ( uint32_t * ) ( (uint8_t *) (void *)((uint8_t *)dw_SAMPBaseAddress + SAMP_KILL_INFO_OFFSET) );
	if ( isBadPtr_writeAny(p_DeathList, sizeof(stKillInfo)) )
		return;
	t=true;

	
	}	
}


D3DCOLOR SAMPBase::samp_color_get ( int id, DWORD trans )
{
	if ( dw_SAMPBaseAddress == NULL )
		return NULL;

	D3DCOLOR	*color_table;
	if ( id < 0 || id >= (SAMP_PLAYER_MAX + 3) )
		return D3DCOLOR_ARGB( 0xFF, 0x99, 0x99, 0x99 );

	switch ( id )
	{
	case ( SAMP_PLAYER_MAX ):
		return 0xFF888888;

	case ( SAMP_PLAYER_MAX + 1 ):
		return 0xFF0000AA;

	case ( SAMP_PLAYER_MAX + 2 ):
		return 0xFF63C0E2;
	}

	color_table = ( D3DCOLOR * ) ( (uint8_t *)dw_SAMPBaseAddress + SAMP_COLOR_OFFSET );
	return ( color_table[id] >> 8 ) | trans;
}

#define FUNC_ADDTOCHATWND	0x5F060
void SAMPBase::AddToChatWindow(char* text,DWORD textColor,int playerID)
{
	if(p_SAMP == NULL || p_Chat == NULL)
		return;

	if( text == NULL)
		return;

	if( playerID < -1)
		playerID = -1;

	uint32_t chatinfo = dw_SAMPBaseAddress + SAMP_CHAT_INFO_OFFSET;
	uint32_t func = dw_SAMPBaseAddress + FUNC_ADDTOCHATWND;

	if( playerID != -1)
	{
		char * playerName = (char*)"XForce";//getPlayerName(playerID);
		if(playerName == NULL)
			return;

		DWORD playerColor = samp_color_get(playerID);

		__asm
		{
			mov eax , dword ptr[chatinfo]
			mov ecx, dword ptr[eax]
			push playerColor
			push textColor
			push playerName
			push text
			push 10
			call func
		}
		return;
	}

	__asm 
	{
		mov eax, dword ptr[chatinfo]
		mov ecx, dword ptr[eax]
		push 0
		push textColor
		push 0
		push text
		push 12
		call func
	}
	return;
}
#define FUNC_SENDCMD	0x60910
void SAMPBase::SendCommandToServer(char* msg)
{
	if(p_SAMP == NULL)
		return;

	if(msg == NULL)
		return;

	uint32_t func = dw_SAMPBaseAddress + FUNC_SENDCMD;
	__asm push msg
	__asm call func

}